package wx.controls
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	
	import wx.core.ITheme;
	import wx.core.SettingCache;
	import wx.motion.Tween;
	
	/**
	 * 
	 * @author wujianqi
	 * 滚动容器
	 * 
	 */	
	public class Scroller extends ContainerBase
	{
		
		public static const HORIZONTAL:String = "horizontal";
		public static const VERTICAL:String = "vertical";
		public static const NONE:String = "none";
		
		private var _hbarSkin:DisplayObject;		
		private var _vbarSkin:DisplayObject;
	
		private var _maskWidth:Number = SettingCache.mainWidth;
		private var _maskHeight:Number = SettingCache.mainHeight;		
		private var _maskSpace:Space = new Space(_maskWidth,_maskHeight);
		private var _backgroundSpace:Space =  new Space();
		
		private var _content:Sprite;
		
		public var direction:String = NONE;
		
		private const _theme:ITheme = SettingCache.theme;
		
		public function Scroller($width:Object=null,$height:Object=null)
		{
			super();
			
			if($width){
				_maskWidth = $width as Number;
				_maskSpace.width = _maskWidth;
			}
			if($height){
				_maskHeight = $height as Number;
				_maskSpace.height = _maskHeight;
			}
			
			contentGroup  = new Sprite();
			_content = contentGroup as Sprite;			
			_content.addChild(_backgroundSpace);
			_content.mask = _maskSpace;
			//overlay = new Sprite();
			//addBar();
			
			updateContent();			
			bindEvent();
			
		} 
		
		private function bindEvent():void{
			if(!_content.hasEventListener(MouseEvent.MOUSE_DOWN))
				_content.addEventListener(MouseEvent.MOUSE_DOWN,onStart);
		}	
	
		
		private function unbindEvent():void{			
			_content.removeEventListener(MouseEvent.MOUSE_DOWN,onStart);
		}
		
		/**
		 * 
		 * 开始拖动
		 * 
		 */		
		private function onStart(e:MouseEvent):void{
			var rect:Rectangle;
			switch(direction)
			{
				case NONE:
				{
					_content.startDrag(false);	
					break;
				}
				case HORIZONTAL:
				{
					rect = new Rectangle(-_content.width,0,_content.width*2,0);
					_content.startDrag(false,rect);
					break;	
				}
				case VERTICAL:
				{
					rect = new Rectangle(0,-_content.height,0,_content.height*2);
					_content.startDrag(false,rect);
					break;
				}
			}
			
			//stage.addEventListener(MouseEvent.MOUSE_MOVE,onMove);
			stage.addEventListener(MouseEvent.MOUSE_UP,onEnd);
		}
		
		/**
		 * 
		 * 结束拖动，判断偏离，缓动归位
		 * 
		 */		
		private function onEnd(e:MouseEvent):void{
			
			_content.stopDrag();
			stage.removeEventListener(MouseEvent.MOUSE_UP,onEnd);
			//stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMove);
			//reset();
			
			var hasLeftOffset:Boolean = _content.x>0,
				hasTopOffset:Boolean = _content.y>0,
				hasRightOffset:Boolean = (_content.width + _content.x)<_maskWidth,
				hasBottomOffset:Boolean = (_content.height + _content.y)<_maskHeight,
				nx:Number =_content.x ,
				ny:Number = _content.y,
				nw:Number = _content.width<_maskWidth ? 0 :_maskWidth- _content.width,
				nh:Number = _content.height<_maskHeight ? 0 :_maskHeight-_content.height;			
			
			if(hasLeftOffset) nx = 0;
			if(hasTopOffset) ny = 0;
			if(hasRightOffset) nx = nw;
			if(hasBottomOffset) ny = nh;

			if(nx!=_content.x || ny!=_content.y)
				new Tween(_content,0.2,{x:nx,y:ny},{ease:Tween.Quartic});
			
			
		}
		
		private function addBar():void{			
			if(direction==NONE || direction==HORIZONTAL){
				_hbarSkin = _theme.horizontalScrollerBarSkin;
				_hbarSkin.y = _maskHeight - _hbarSkin.height;						
				//_hbarSkin.visible = false;
				if(!overlay.contains(_hbarSkin)) overlay.addChild(_hbarSkin);
			}			
			
			if(direction==NONE || direction==VERTICAL){
				_vbarSkin = _theme.verticalScrollerBarSkin;
				_vbarSkin.alpha = 0.5;
				//_vbarSkin.visible = false;
				_vbarSkin.x = _maskWidth - _vbarSkin.width;
				if(!overlay.contains(_hbarSkin)) overlay.addChild(_hbarSkin);
			}			
		}
		
		/**
		 * 计算滚动条位置
		 * 
		 */		
		private function onMove(e:MouseEvent):void{
			if(direction==NONE || direction==HORIZONTAL){			
				var hasLeftOffset:Boolean = _content.x>0,					
					hasRightOffset:Boolean = (_content.width + _content.x)<_maskWidth;
				
				if(hasLeftOffset){
					_hbarSkin.x = 0;

				}else if(hasRightOffset){
					_hbarSkin.x = _maskWidth-_hbarSkin.width;
					
				}else{
					
					_hbarSkin.x = -_content.x*_hbarSkin.width/_maskWidth;
					//trace(_hbarSkin.x);
					//trace(_hbarSkin.width/_maskWidth);
					//_hbarSkin.x  = -_hbarSkin.width*(_content.x/_maskWidth);
				}
				
				
			}
			if(direction==NONE || direction==VERTICAL){
				_vbarSkin.height = _maskHeight;
			}			
		}
		
		private function reset():void{
			if(direction==NONE || direction==HORIZONTAL){
				//_hbarSkin.x  = _beginHbarPoint.x;
				//_hbarSkin.y  = _beginHbarPoint.y;

			}
			if(direction==NONE || direction==VERTICAL){
				
			}
		}

		
		/**
		 * 
		 * 遮罩位置自适应
		 * 
		 */		
		override public function set x(value:Number):void{
			_maskSpace.x = value;
			super.x = value;
		}
		override public function set y(value:Number):void{
			//_maskSpace.y = stage.localToGlobal(new Point(this.x,value))).y;
			_maskSpace.y = value;
			super.y = value;
		}
		
		/**
		 * 设置空白背景拖动范围,非满屏/透明区内容也能拖动
		 * 
		 */		
		private function resizeBackground():void{				
			_backgroundSpace.width = _content.width<_maskWidth ? _maskWidth :_content.width;
			_backgroundSpace.height = _content.height<_maskHeight ? _maskHeight:_content.height;
		}
		override public function addChild(child:DisplayObject):DisplayObject{
			var child:DisplayObject =  super.addChild(child);
			resizeBackground();
			return child;
		}		
		override public function addChildAt(child:DisplayObject,index:int):DisplayObject{
			var child:DisplayObject = super.addChildAt(child,index);
			resizeBackground();		
			return child;
		}
		
		
		override public function set width(value:Number):void{			
			_maskWidth = value;
			_maskSpace.width = value;
		}
		override public function set height(value:Number):void{			
			_maskHeight = value;
			_maskSpace.height = value;
			trace(value);
		}
		
		override protected function dispose():void{
			unbindEvent();
		}
		
		
		
	}
}